#!/usr/bin/env node

const fs = require('fs');
const path = require('path');
const os = require('os');
const { execSync } = require('child_process');

// Paths
const homeDir = os.homedir();
const superpowersSkillsDir = path.join(homeDir, '.codex', 'superpowers', 'skills');
const personalSkillsDir = path.join(homeDir, '.codex', 'skills');
const bootstrapFile = path.join(homeDir, '.codex', 'superpowers', '.codex', 'superpowers-bootstrap.md');
const superpowersRepoDir = path.join(homeDir, '.codex', 'superpowers');

// Utility functions
function checkForUpdates() {
    try {
        // Quick check with 3 second timeout to avoid delays if network is down
        const output = execSync('git fetch origin && git status --porcelain=v1 --branch', {
            cwd: superpowersRepoDir,
            timeout: 3000,
            encoding: 'utf8',
            stdio: 'pipe'
        });

        // Parse git status output to see if we're behind
        const statusLines = output.split('\n');
        for (const line of statusLines) {
            if (line.startsWith('## ') && line.includes('[behind ')) {
                return true; // We're behind remote
            }
        }
        return false; // Up to date
    } catch (error) {
        // Network down, git error, timeout, etc. - don't block bootstrap
        return false;
    }
}

function extractFrontmatter(filePath) {
    try {
        const content = fs.readFileSync(filePath, 'utf8');
        const lines = content.split('\n');

        let inFrontmatter = false;
        let name = '';
        let description = '';
        let whenToUse = '';

        for (const line of lines) {
            if (line.trim() === '---') {
                if (inFrontmatter) break;
                inFrontmatter = true;
                continue;
            }

            if (inFrontmatter) {
                const match = line.match(/^(\w+):\s*(.*)$/);
                if (match) {
                    const [, key, value] = match;
                    switch (key) {
                        case 'name': name = value.trim(); break;
                        case 'description': description = value.trim(); break;
                        case 'when_to_use': whenToUse = value.trim(); break;
                    }
                }
            }
        }

        return { name, description, whenToUse };
    } catch (error) {
        return { name: '', description: '', whenToUse: '' };
    }
}

function printSkill(skillPath, sourceType) {
    const skillFile = path.join(skillPath, 'SKILL.md');
    const relPath = sourceType === 'personal'
        ? path.relative(personalSkillsDir, skillPath)
        : path.relative(superpowersSkillsDir, skillPath);

    // Print skill name with namespace
    if (sourceType === 'personal') {
        console.log(relPath.replace(/\\/g, '/')); // Personal skills are not namespaced
    } else {
        console.log(`superpowers:${relPath.replace(/\\/g, '/')}`); // Superpowers skills get superpowers namespace
    }

    // Extract and print metadata
    const { name, description, whenToUse } = extractFrontmatter(skillFile);

    if (description) console.log(`  ${description}`);
    if (whenToUse) console.log(`  When to use: ${whenToUse}`);
    console.log('');
}

function findSkillsInDir(dir, sourceType, maxDepth = 1) {
    const skills = [];

    if (!fs.existsSync(dir)) return skills;

    function searchDir(currentDir, currentDepth) {
        if (currentDepth > maxDepth) return;

        try {
            const entries = fs.readdirSync(currentDir, { withFileTypes: true });

            for (const entry of entries) {
                if (entry.isDirectory()) {
                    const skillDir = path.join(currentDir, entry.name);
                    const skillFile = path.join(skillDir, 'SKILL.md');

                    if (fs.existsSync(skillFile)) {
                        skills.push(skillDir);
                    }

                    // For personal skills, search deeper (category/skill structure)
                    if (sourceType === 'personal' && currentDepth < maxDepth) {
                        searchDir(skillDir, currentDepth + 1);
                    }
                }
            }
        } catch (error) {
            // Ignore permission errors or other issues
        }
    }

    searchDir(dir, 0);
    return skills;
}

// Commands
function runFindSkills() {
    console.log('Available skills:');
    console.log('==================');
    console.log('');

    const foundSkills = new Set();

    // Find personal skills first (these take precedence)
    const personalSkills = findSkillsInDir(personalSkillsDir, 'personal', 2);
    for (const skillPath of personalSkills) {
        const relPath = path.relative(personalSkillsDir, skillPath);
        foundSkills.add(relPath);
        printSkill(skillPath, 'personal');
    }

    // Find superpowers skills (only if not already found in personal)
    const superpowersSkills = findSkillsInDir(superpowersSkillsDir, 'superpowers', 1);
    for (const skillPath of superpowersSkills) {
        const relPath = path.relative(superpowersSkillsDir, skillPath);
        if (!foundSkills.has(relPath)) {
            printSkill(skillPath, 'superpowers');
        }
    }

    console.log('Usage:');
    console.log('  superpowers-codex use-skill <skill-name>   # Load a specific skill');
    console.log('');
    console.log('Skill naming:');
    console.log('  Superpowers skills: superpowers:skill-name (from ~/.codex/superpowers/skills/)');
    console.log('  Personal skills: skill-name (from ~/.codex/skills/)');
    console.log('  Personal skills override superpowers skills when names match.');
    console.log('');
    console.log('Note: All skills are disclosed at session start via bootstrap.');
}

function runBootstrap() {
    console.log('# Superpowers Bootstrap for Codex');
    console.log('# ================================');
    console.log('');

    // Check for updates (with timeout protection)
    if (checkForUpdates()) {
        console.log('## Update Available');
        console.log('');
        console.log('⚠️  Your superpowers installation is behind the latest version.');
        console.log('To update, run: `cd ~/.codex/superpowers && git pull`');
        console.log('');
        console.log('---');
        console.log('');
    }

    // Show the bootstrap instructions
    if (fs.existsSync(bootstrapFile)) {
        console.log('## Bootstrap Instructions:');
        console.log('');
        try {
            const content = fs.readFileSync(bootstrapFile, 'utf8');
            console.log(content);
        } catch (error) {
            console.log(`Error reading bootstrap file: ${error.message}`);
        }
        console.log('');
        console.log('---');
        console.log('');
    }

    // Run find-skills to show available skills
    console.log('## Available Skills:');
    console.log('');
    runFindSkills();

    console.log('');
    console.log('---');
    console.log('');

    // Load the using-superpowers skill automatically
    console.log('## Auto-loading superpowers:using-superpowers skill:');
    console.log('');
    runUseSkill('superpowers:using-superpowers');

    console.log('');
    console.log('---');
    console.log('');
    console.log('# Bootstrap Complete!');
    console.log('# You now have access to all superpowers skills.');
    console.log('# Use "superpowers-codex use-skill <skill>" to load and apply skills.');
    console.log('# Remember: If a skill applies to your task, you MUST use it!');
}

function runUseSkill(skillName) {
    if (!skillName) {
        console.log('Usage: superpowers-codex use-skill <skill-name>');
        console.log('Examples:');
        console.log('  superpowers-codex use-skill superpowers:brainstorming  # Load superpowers skill');
        console.log('  superpowers-codex use-skill brainstorming              # Load personal skill (or superpowers if not found)');
        console.log('  superpowers-codex use-skill my-custom-skill            # Load personal skill');
        return;
    }

    // Handle namespaced skill names
    let actualSkillPath;
    let forceSuperpowers = false;

    if (skillName.startsWith('superpowers:')) {
        // Remove the superpowers: namespace prefix
        actualSkillPath = skillName.substring('superpowers:'.length);
        forceSuperpowers = true;
    } else {
        actualSkillPath = skillName;
    }

    // Remove "skills/" prefix if present
    if (actualSkillPath.startsWith('skills/')) {
        actualSkillPath = actualSkillPath.substring('skills/'.length);
    }

    // Function to find skill file
    function findSkillFile(searchPath) {
        // Check for exact match with SKILL.md
        const skillMdPath = path.join(searchPath, 'SKILL.md');
        if (fs.existsSync(skillMdPath)) {
            return skillMdPath;
        }

        // Check for direct SKILL.md file
        if (searchPath.endsWith('SKILL.md') && fs.existsSync(searchPath)) {
            return searchPath;
        }

        return null;
    }

    let skillFile = null;

    // If superpowers: namespace was used, only check superpowers skills
    if (forceSuperpowers) {
        if (fs.existsSync(superpowersSkillsDir)) {
            const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
            skillFile = findSkillFile(superpowersPath);
        }
    } else {
        // First check personal skills directory (takes precedence)
        if (fs.existsSync(personalSkillsDir)) {
            const personalPath = path.join(personalSkillsDir, actualSkillPath);
            skillFile = findSkillFile(personalPath);
            if (skillFile) {
                console.log(`# Loading personal skill: ${actualSkillPath}`);
                console.log(`# Source: ${skillFile}`);
                console.log('');
            }
        }

        // If not found in personal, check superpowers skills
        if (!skillFile && fs.existsSync(superpowersSkillsDir)) {
            const superpowersPath = path.join(superpowersSkillsDir, actualSkillPath);
            skillFile = findSkillFile(superpowersPath);
            if (skillFile) {
                console.log(`# Loading superpowers skill: superpowers:${actualSkillPath}`);
                console.log(`# Source: ${skillFile}`);
                console.log('');
            }
        }
    }

    // If still not found, error
    if (!skillFile) {
        console.log(`Error: Skill not found: ${actualSkillPath}`);
        console.log('');
        console.log('Available skills:');
        runFindSkills();
        return;
    }

    // Extract frontmatter and content
    let content, frontmatter;
    try {
        const fullContent = fs.readFileSync(skillFile, 'utf8');
        const { name, description, whenToUse } = extractFrontmatter(skillFile);

        // Extract just the content after frontmatter
        const lines = fullContent.split('\n');
        let inFrontmatter = false;
        let frontmatterEnded = false;
        const contentLines = [];

        for (const line of lines) {
            if (line.trim() === '---') {
                if (inFrontmatter) {
                    frontmatterEnded = true;
                    continue;
                }
                inFrontmatter = true;
                continue;
            }

            if (frontmatterEnded || !inFrontmatter) {
                contentLines.push(line);
            }
        }

        content = contentLines.join('\n').trim();
        frontmatter = { name, description, whenToUse };
    } catch (error) {
        console.log(`Error reading skill file: ${error.message}`);
        return;
    }

    // Display skill header with clean info
    const displayName = forceSuperpowers ? `superpowers:${actualSkillPath}` :
                       (skillFile.includes(personalSkillsDir) ? actualSkillPath : `superpowers:${actualSkillPath}`);

    const skillDirectory = path.dirname(skillFile);

    console.log(`# ${frontmatter.name || displayName}`);
    if (frontmatter.description) {
        console.log(`# ${frontmatter.description}`);
    }
    if (frontmatter.whenToUse) {
        console.log(`# When to use: ${frontmatter.whenToUse}`);
    }
    console.log(`# Supporting tools and docs are in ${skillDirectory}`);
    console.log('# ============================================');
    console.log('');

    // Display the skill content (without frontmatter)
    console.log(content);

}

// Main CLI
const command = process.argv[2];
const arg = process.argv[3];

switch (command) {
    case 'bootstrap':
        runBootstrap();
        break;
    case 'use-skill':
        runUseSkill(arg);
        break;
    case 'find-skills':
        runFindSkills();
        break;
    default:
        console.log('Superpowers for Codex');
        console.log('Usage:');
        console.log('  superpowers-codex bootstrap              # Run complete bootstrap with all skills');
        console.log('  superpowers-codex use-skill <skill-name> # Load a specific skill');
        console.log('  superpowers-codex find-skills            # List all available skills');
        console.log('');
        console.log('Examples:');
        console.log('  superpowers-codex bootstrap');
        console.log('  superpowers-codex use-skill superpowers:brainstorming');
        console.log('  superpowers-codex use-skill my-custom-skill');
        break;
}